package com.updesignsz.commom.util;

import java.io.Serializable;
import java.util.*;

/**
 * 分页请求信息
 */
public class PageRequest implements Serializable {
    private static final long serialVersionUID = 4047115735625926686L;

    private Map<String, Object> filters = new HashMap<String, Object>(); // 查询过滤参数
    private Integer pageNumber; // 页号码,页码从1开始
    private Integer pageSize; // 分页大小
    private String sortColumns; // 排序的多个列, 如: username desc

    public PageRequest() {
    }

    public Map<String, Object> getFilters() {
        if (StringUtil.isNotEmpty(sortColumns)) {
            filters.put("sortColumns", sortColumns);
        }
        return filters;
    }

    public PageRequest setFilters(Map<String, Object> filters) {
        this.filters = filters;
        return this;
    }

    public String replaceQueryStr(String queryStr, String name, Object value) {
        if (StringUtil.isNotBlank(queryStr)) {
            queryStr = queryStr.replaceAll(name + "=.*?($|&)", "").replaceFirst("&$", "");
        }
        return addParam(queryStr, name, value);
    }

    public String addParam(String str, String name, Object value) {
        str = StringUtil.isBlank(str) ? "" : str + "&";
        return str + name + "=" + value;
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public PageRequest setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber <= 0 ? 1 : pageNumber;
        return this;
    }

    public int getPageSize() {
        return pageSize;
    }

    public PageRequest setPageSize(int pageSize) {
        this.pageSize = pageSize;
        return this;
    }

    public String getSortColumns() {
        return sortColumns;
    }

    /**
     * 排序的列,可以同时多列,使用逗号分隔,如 username desc,age asc
     */
    public PageRequest setSortColumns(String sortColumns) {
        checkSortColumnsSqlInjection(sortColumns);
        if (sortColumns != null && sortColumns.length() > 50)
            throw new IllegalArgumentException("sortColumns.length() must be less than 50");
        this.sortColumns = sortColumns;
        return this;
    }

    /**
     * 将sortColumns进行解析以便返回SortInfo以便使用
     */
    public List<SortInfo> getSortInfos() {
        return Collections.unmodifiableList(SortInfo.parseSortColumns(sortColumns));
    }

    private void checkSortColumnsSqlInjection(String sortColumns) {
        if (sortColumns == null)
            return;
        if (sortColumns.contains("'") || sortColumns.contains("\\"))
            throw new IllegalArgumentException("sortColumns:" + sortColumns + " has SQL Injection risk");
    }

    /**
     * 排序的列
     */
    public static class SortInfo implements Serializable {
        private static final long serialVersionUID = 6959974032209696722L;

        private String columnName;
        private String sortOrder;

        public SortInfo() {
        }

        public SortInfo(String columnName, String sortOrder) {
            this.columnName = columnName;
            this.sortOrder = sortOrder;
        }

        public String getColumnName() {
            return columnName;
        }


        public String getSortOrder() {
            return sortOrder;
        }

        public void setColumnName(String columnName) {
            this.columnName = columnName;
        }

        public void setSortOrder(String sortOrder) {
            this.sortOrder = sortOrder;
        }

        public static List<SortInfo> parseSortColumns(String sortColumns) {
            if (sortColumns == null) {
                return Collections.emptyList();
            }

            List<SortInfo> results = new ArrayList<SortInfo>();
            String[] sortSegments = sortColumns.trim().split(",");
            for (String sortSegment : sortSegments) {
                String[] array = sortSegment.split("\\s+");

                SortInfo sortInfo = new SortInfo();
                sortInfo.setColumnName(array[0]);
                sortInfo.setSortOrder(array.length == 2 ? array[1] : null);
                results.add(sortInfo);
            }
            return results;
        }

        @Override
        public String toString() {
            return columnName + (sortOrder == null ? "" : " " + sortOrder);
        }
    }
}